import {CtlBase} from "../../CtlBase";
import {parseYvanPropChangeVJson} from "../../CtlUtils";
import webix from 'webix'
import {DataSource} from "../../YvanDataSource";
import {YvDataSource} from "../../YvanDataSourceImp";
import {CtlCheckboxGroupDefault} from "../../CtlDefaultValue";
import { YvEvent, YvEventDispatch } from '../../YvanEvent'
import * as YvanMessage from "../../YvanUIMessage";

export class CtlCheckBoxGroup extends CtlBase<CtlCheckBoxGroup> {
    static create(module: any, vjson: any): CtlCheckBoxGroup {
        const that = new CtlCheckBoxGroup(vjson)
        that._module = module

        _.defaultsDeep(vjson, CtlCheckboxGroupDefault)

        that._viewPlaceId = "thePlace"+webix.uid();
        const yvanProp = parseYvanPropChangeVJson(vjson, [
            'dataSource',
            'label',
            'view',
            'labelWidth',
            'labelAlign',
            'onChange',
            'required',
            'hidden',
            'onValidate',
            'isHideTooltip'
        ])

        // 将 yvanProp 合并至当前 Ctl 对象
        _.assign(that, yvanProp)

        // 将 _webixConfig 合并至 vjson, 最终合交给 webix 做渲染
        _.merge(vjson, {
            css:'checkboxGroupWrap',
            cols:[
                {
                    view: 'label',
                    label: that.label,
                    width: that.labelWidth,
                    align: that.labelAlign
                },
                {
                    view: 'template',
                    id: that._viewPlaceId,
                    on: {
                        onInited(this: any) {
                            that.attachHandle(this, {...vjson, ...yvanProp})
                        },
                        onDestruct(this: any) {
                            that._hideTootip()
                            that.removeHandle()
                        }
                    }
                }
            ]
        })

        return that
    }

    /**
     * 赋值的时候
     */
    set dataReal(nv: any[]) {
        this.groupData = nv
        const that=this;
        //this.entityName
        if(this._required||this.onValidate){
            const result = that._resultToShowOrHide()
            if (result) {
                that._showValidateError()
            } else {
                that._hideValidateError();
            }
        }
        $('div[view_id='+this._viewPlaceId+'] .webix_template').addClass('itemCheckbox').empty();
        _.forEach(nv, item => {
            const list=$('<input type="checkbox" value='+item.id+'><span>'+item.text+'</span>');
            if(that.value.indexOf(item.id) != -1) {
                list.prop("checked",true)
            }
            $('div[view_id='+that._viewPlaceId+'] .webix_template').append(list);
            $(list[0]).on('change',function(n:any,b){
                let oldValue=that._value;
                that._value='';
                that._unCheckedValue = '';
                let clickId = n.target.value;
                $('div[view_id='+that._viewPlaceId+'] .webix_template input').each(function(index,el){
                    if($(el).is(':checked')){
                        if (that._value) {
                            that._value = that._value + ',' + $(el).val()
                        }
                        else {
                            that._value = <string>$(el).val()
                        }
                    }
                    else{
                        if (that._unCheckedValue) {
                            that._unCheckedValue = that._unCheckedValue + ',' + $(el).val()
                        }
                        else {
                            that._unCheckedValue = <string>$(el).val()
                        }
                    }
                })
                YvEventDispatch(that.onChange, that,{newV:that._value, oldV:oldValue, clickId:clickId, uncheck:that._unCheckedValue});
                that.changeToEntity(that._value);

                const result = that._resultToShowOrHide()
                if (result) {
                    that._showValidateError()
                    that._showTootip(result);
                } else {
                    that._hideValidateError();
                    that._hideTootip()
                }
            })
        })
    }

    _viewPlaceId: string = ''
    label: string = ''
    labelWidth: number = 100
    labelAlign: string = 'right'
    itemCheckboxIds: any[] = []
    groupData: any[] = []
    _required: boolean = false
    /**
     * 校验事件
     */
    onValidate?: YvEvent<any, string> | undefined
    isHideTooltip?: boolean = false

    //数据源设置
    private _dataSource: DataSource<CtlCheckBoxGroup>
    //数据源管理器
    private dataSourceBind?: YvDataSource<CtlCheckBoxGroup>

    /**
     * 必填
     */
    set required(nv: boolean) {
        this._required = nv
    }

    _showValidateError() {
        $(this._webix.$view).addClass('yvan-validate-error checkbox-error-wrap');
    }

    _hideValidateError() {
        $(this._webix.$view).removeClass('yvan-validate-error');
    }

    _showTootip(msg: string) {
        if (!this.isHideTooltip) {
            YvanMessage.showTooltip(this, msg);
        }
    }

    _hideTootip() {
        if (!this.isHideTooltip) {
            YvanMessage.hideTooltip(this);
        }
    }

    _resultToShowOrHide(): any {
        if (!this.value && this._required) {
            return this.vjson.label + "必填";
        }
        else {
            // 只有校验值
            const that = this;
            const result = YvEventDispatch(this.onValidate, that, this.value);
            if (result) {
                return result
            }
        }
        return null
    }

    /**
     * 获取数据源设置
     */
    get dataSource(): DataSource<CtlCheckBoxGroup> {
        return this._dataSource
    }

    /**
     * 设置数据源
     */
    set dataSource(nv: DataSource<CtlCheckBoxGroup>) {
        this._dataSource = nv
            // onLoad 之后会触发 view.onInited -> attachHandle -> refreshState -> _rebindDataSource
            // onLoad 之前都不需要主动触发 _rebindDataSource
        this._rebindDataSource()
    }

    //重新绑定数据源
    private _rebindDataSource() {
        if (!this._module) {
            return;
        }

        const innerMethod = () => {
            if (this.dataSourceBind) {
                this.dataSourceBind.destory()
                this.dataSourceBind = undefined
            }

            if (this._viewPlaceId && this._module) {
                this.dataSourceBind = new YvDataSource(this, this.dataSource, this._dataSourceProcess.bind(this))
                this.dataSourceBind.init()
            }
        }

        if (!this._module.loadFinished) {
            // onload 函数还没有执行（模块还没加载完）, 延迟调用 rebind
            _.defer(innerMethod)

        } else {
            // 否则实时调用 rebind
            innerMethod()
        }
    }

    private _dataSourceProcess(data: any[]) {
        if (
            !this.dataSource ||
            _.isArray(this.dataSource) ||
            _.isFunction(this.dataSource)
        ) {
            return data
        }

        if (this.dataSource.type !== 'SQL') {
            return data
        }

        const displayField = this.dataSource.displayField || 'text'
        const valueField = this.dataSource.valueField || 'id'
        return _.map(data, item => {
            return {
                id: item[valueField],
                text: item[displayField]
            }
        })
    }

    /**
     * 重新请求数据
     */
    public reload(): void {
        if (this.dataSourceBind && this.dataSourceBind.reload) {
            this.dataSourceBind.reload()
        }
    }

    /**
     * 获取选项值
     */
    public getGroupValue() {
        const values: any[] = []
        _.forEach(this.itemCheckboxIds, id => {
            // @ts-ignore
            const va = webix.$$(id).getValue()
            values.push(va)
        })
        return values
    }
    
    /**
       * 设置值
       */
    set value(nv: any) {
        const that=this;
        if(nv.length>0){
            const nvArr = nv.split(',');
            const _inputArr=$(this._webix.$view).find('input[type="checkbox"]');
            _inputArr.each(function(index,el){//清空组件全部选中状态
                $(el).prop("checked",false);
            })
           $(nvArr).each(function (i,val){//根据值，动态选中对应的checkbox
                $(that._webix.$view).find('input[value="'+val+'"]').prop("checked",true);
            })
        }
        this._value = nv;
    }
    
      /**
       * 获取值
       */
    get value(): any {
        return this._value;
    }

    get unCheckedValue(): any {
        return this._unCheckedValue
    }

    private _value: string = ''
    private _unCheckedValue: string = ''
    onChange?: YvEvent<CtlCheckBoxGroup, string>
}